package com.annchain.og_browser.controller;

import com.annchain.og_browser.entity.OgbBlock;
import com.annchain.og_browser.entity.OgbTransaction;
import com.annchain.og_browser.service.OgbBlockService;
import com.annchain.og_browser.service.impl.IpServiceImpl;
import com.annchain.og_browser.service.impl.OgbTransactionServiceImpl;
import com.annchain.og_browser.vo.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/blockchain")
@Api(description = "区块接口")
public class OgbBlockController {
    private static final Logger logger = LoggerFactory.getLogger(OgbBlockController.class);
    private final String CLASS_NAME = this.getClass().getSimpleName();

    private static final int HASH_LENGTH = 66;
    private static final int HEX_PREFIX_LENGTH = 2;

    @Autowired
    private OgbBlockService ogbBlockService;
    @Autowired
    private OgbTransactionServiceImpl ogbTransactionService;
    @Autowired
    private IpServiceImpl ipService;


    @ApiOperation("返回最新区块列表")
    @GetMapping("/blocklist")
    public JsonResponse<BasePageResponse<List<LatestBlockVO>>> findData(Integer pageNum, Integer pageSize) {
        logger.info("########{}.{} begin...", CLASS_NAME, Thread.currentThread().getStackTrace()[1].getMethodName());

        BasePageResponse response = ogbBlockService.findData(pageNum,pageSize);
        return JsonResponse.success(response).setCode(200).setMsg("成功");
    }

    @ApiOperation("根据区块高度或者哈希查询区块")
    @GetMapping("/block/{param}")
    public JsonResponse<OgbBlockVO> findBlockByParam(@PathVariable String param) {
        logger.info("########{}.{} begin...", CLASS_NAME, Thread.currentThread().getStackTrace()[1].getMethodName());
        logger.info("param:{}", param);

        param = param.trim();
        if (param.length() == HASH_LENGTH || param.length() == HASH_LENGTH - HEX_PREFIX_LENGTH) {
            if (param.length() == HASH_LENGTH) {
                param = param.substring(HEX_PREFIX_LENGTH);
            }
            OgbBlockVO ogbBlockVO = ogbBlockService.findByHash(param);
            if (ogbBlockVO == null) {
                return JsonResponse.serverError();
            }

            return JsonResponse.success(ogbBlockVO).setMsg("成功");
        }
        else if (StringUtils.isNumeric(param) && param.length() < 10){
            int Height = Integer.parseInt(param);
            OgbBlockVO ogbBlockVO = ogbBlockService.findByHeight(Height);
            if (ogbBlockVO == null) {
                return JsonResponse.serverError();
            }
            return JsonResponse.success(ogbBlockVO).setCode(200).setMsg("查询成功");
        } else {
            return JsonResponse.parameterError("输入数据有误").setCode(400);
        }
    }

    @ApiOperation("首页搜索框的查询接口")
    @GetMapping("/all")
    public JsonResponse<Object> findAllByParam(String param) {
        logger.info("########{}.{} begin...", CLASS_NAME, Thread.currentThread().getStackTrace()[1].getMethodName());
        logger.info("param:{}", param);


        param = param.trim();

        //判断是否为高度
        if (StringUtils.isNumeric(param) && param.length() < 30) {
            int Height = Integer.parseInt(param);
            OgbBlockVO ogbBlockVO = ogbBlockService.findByHeight(Height);
            if (ogbBlockVO == null) {
                return JsonResponse.serverError();
            }
            return JsonResponse.success(ogbBlockVO).setCode(200).setMsg("查询成功");
        }
        //判断是否为hash,分为交易hash和区块hash
        else if (param.length() == HASH_LENGTH && param.substring(0,2).equals("0x") || param.length() == 64){
            if (param.length() == HASH_LENGTH && param.substring(0,2).equals("0x")) {
                param = param.substring(HEX_PREFIX_LENGTH);
            }

            OgbTransaction ogbTransaction = ogbTransactionService.findByHash(param);
            //查出来是交易的情况
            if (ogbTransaction != null) {
                switch (ogbTransaction.getType()) {
                    case 0:
                        TransferTxVO transferTxVO = ogbTransactionService.findTransferByTxHash(param);
                        return JsonResponse.success(transferTxVO).setCode(200).setMsg("成功");
                    case 4:
                        DepositeTxVO depositeTxVO = ogbTransactionService.findDepositeByTxHash(param);
                        return JsonResponse.success(depositeTxVO).setCode(200).setMsg("成功");
                    case 5:
                        IssueTxVO issueTxVO = ogbTransactionService.findIssueByTxHash(param);
                        return JsonResponse.success(issueTxVO).setCode(200).setMsg("成功");
                }
            } else {
                //查出来是区块的情况
                OgbBlockVO ogbBlockVO = ogbBlockService.findByHash(param);
                if (ogbBlockVO != null)
                    return JsonResponse.success(ogbBlockVO).setCode(200).setMsg("成功");
            }
        }
        //都不是则输入数据有误
        return JsonResponse.parameterError("输入的数据有误").setCode(400);
    }

    @PostMapping("/insertKnonwAddress")
    public void addKnownAddress(String address, String name, String url) {
        ogbBlockService.addKonwnAddress(address,name,url);
    }

    @GetMapping("/nodeBrowse")
    public JsonResponse<PerformanceVO> findAll() {
        logger.info("########{}.{} begin...", CLASS_NAME, Thread.currentThread().getStackTrace()[1].getMethodName());

        PerformanceVO performanceVO = ogbBlockService.findAll();
        return JsonResponse.success(performanceVO).setCode(200).setMsg("查询成功");
    }

}
